#pragma once 
#include"Sem.hpp"
#include"Mutex.hpp"
#include<vector>
#define gcap 5
namespace kzz
{
    template<class T>
    class RingQueeu
    {

        public:
        RingQueeu(int cap=gcap)
        :_cap(cap)
        ,_rq(cap)
        ,_blank_sem(cap)
        ,_p_step(0)
        ,_data_sem(0)
        ,_c_step(0)
        ,_p_mutex()
        ,_c_mutex()
        {

        }
            //生产者，看_blank_sem
        void Equeue(const T& in)
        {
            //申请空信号量
            _blank_sem.P();
            //使用生产者的锁，
            LockGuard lockguard(_p_mutex);
           // _p_mutex.Lock();
           //生产数据
            _rq[_p_step]=in;
            //控制下表不越界，实现环形
            _p_step++;
            _p_step%=_cap;
            
            //商品信号量增加
            _data_sem.V();
            //解锁
            //_p_mutex.UnLock();


        }
        //消费者，看_data_sem有没有空
        T Pop()
        {
            //申请商品信号量
            _data_sem.P();
            LockGuard lockguard(_c_mutex);
            T data=_rq[_c_step];
            _c_step++;
            _c_step%=_cap;
            _blank_sem.V();
            return data;
        }

        ~RingQueeu()
        {}
        


        private:
        //环形队列
        std::vector<T> _rq;
        int _cap;

        //生产者
        kzz::Sem _blank_sem;
        int _p_step;   //下表

        //消费者
        kzz::Sem _data_sem;
        int _c_step;

        //两把锁
        kzz::Mutex _p_mutex;
        kzz::Mutex _c_mutex;
    };
}